﻿//----------------------------------------------------------------
// Desc: 
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2011-07-08
//
// Update Date : 
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
// 使用方法：
//   class FMDEditSeting : FINI_Muster
//   {
//   public:
//       FINI_bool bWindow;
//   
//       FMDEditSeting()
//           :FINI_Muster(_T("seting"))
//           ,bWindow(_T("window"), true)
//       {
//       }
//       virtual bool Load(IFINI* read)
//       {
//           IFINI* ini = FNewINI();
//           if (ini->Open(_T("..\\assets\\config\\FMDEdit.ini")))
//           {
//               if (FINI_Muster::Load(ini))
//               {
//                   bWindow.load(ini);
//               }
//           }
//           FDelINI(ini);
//           return true;
//       }
//       virtual void Save(IFINIW* write)
//       {
//           IFINIW* ini = FNewINIW(_T("..\\assets\\config\\FMDEdit.ini"));
//           FINI_Muster::Save(ini);
//           bWindow.save(ini);
//           FDelINIW(ini);
//       }
//   };
//   
//   FMDEditSeting kk;
//   bool x = kk.bWindow;
//----------------------------------------------------------------
#pragma once


//----------------------------------------------------------------
// ini文件的某条参数
//----------------------------------------------------------------
template < typename _Ty >
class FINI_Type : public IFMemObject
{
public:
    NCHAR szKey[64];
    _Ty nValue;

    FINI_Type(const NCHAR* name, _Ty default_vl)
    {
        FStrcpy(szKey, name);
        nValue = default_vl;
    }
    FINI_Type()
    {
        FMemzero(szKey, sizeof(szKey));
    }
    void init(const NCHAR* name, _Ty& default_vl)
    {
        FStrcpy(szKey, name);
        nValue = default_vl;
    }
    void lock(_Ty& _min, _Ty& _max)
    {
        if (nValue < _min) nValue = _min;
        if (nValue > _max) nValue = _max;
    }
    void set(_Ty& vl){ nValue = vl; }
    _Ty& get(){ return nValue; }
};


//----------------------------------------------------------------
// 指定类型，其它类型照此写法即可
//----------------------------------------------------------------
#define FINI_TYPE_DEFINE(ty_name, op_func, op_type)\
class FINI_##ty_name : public FINI_Type< op_type >\
{\
    FDECLARE_CLASS(FINI_##ty_name)\
public:\
    FINI_##ty_name(const NCHAR* name, op_type vl)\
        :FINI_Type< op_type >(name, vl)\
    {}\
    FINI_##ty_name()\
    {}\
    op_type operator = (op_type vl)\
    {\
        nValue = vl;\
        return nValue;\
    }\
    operator op_type ()\
    {\
        return nValue;\
    }\
    void load(IFINI* read)\
    {\
        if (read->HasKey(szKey))\
            nValue = (op_type)read->Get##op_func(szKey);\
    }\
    void save(IFINIW* write)\
    {\
        write->Write##op_func(szKey, (op_type)nValue);\
    }\
};

FINI_TYPE_DEFINE(bool, Bool, bool)
FINI_TYPE_DEFINE(int, Int, int)
FINI_TYPE_DEFINE(float, Float, float)
FINI_TYPE_DEFINE(BYTE, Int, int)
FINI_TYPE_DEFINE(WORD, Int, int)
FINI_TYPE_DEFINE(DWORD, Int, int)
FINI_TYPE_DEFINE(Color, Color, DWORD)
class FINI_String : protected FINI_Type< const NCHAR* >
{
    FDECLARE_CLASS(FINI_String)

public:
    NCHAR szValue[MAX_PATH];
    FINI_String(const NCHAR* name, const NCHAR* vl)
        :FINI_Type< const NCHAR* >(name, vl)
    {
        FStrcpy(szValue, vl);
        FMemzero(szValue, sizeof(szValue));
    }
    FINI_String()
    {
        FMemzero(szValue, sizeof(szValue));
    }
    const NCHAR* operator = (const NCHAR* vl)
    {
        FStrcpy(szValue, vl);
        return szValue;
    }
    operator const NCHAR* ()
    {
        return szValue;
    }
    void load(IFINI* read)
    {
        if (read->HasKey(szKey))
            FStrcpy(szValue, read->GetString(szKey));
    }
    void save(IFINIW* write)
    {
        write->WriteString(szKey, szValue);
    }
    void set(const NCHAR* vl){ FStrcpy(szValue, vl); }
    const NCHAR* get(){ return szValue; }
};


//----------------------------------------------------------------
// ini 文件的一个集合，如果只有一个集合，直接继承即可
//----------------------------------------------------------------
class FINI_Muster : public IFMemObject
{
    FDECLARE_CLASS(FINI_Muster)

public:
    NCHAR szName[64];

    FINI_Muster(const NCHAR* name)
    {
        FStrcpy(szName, name);
    }
    virtual~FINI_Muster()
    {
    }
    virtual bool Load(IFINI* read)
    {
        return read->OpenMuster(szName);
    }
    virtual void Save(IFINIW* write)
    {
        write->WriteMuster(szName);
    }
};